﻿//-----------------------------------------------------------------------
// <copyright>
// This file is subject to the terms and conditions of the Microsoft Public License (MS-PL).
// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL for more details.
// </copyright>
//----------------------------------------------------------------------- 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using Fulcrum.ControlGenerator;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Fulcrum.UnitTests.ControlGenerator
{
    [TestClass]
    public class ControlGeneratorGenerationDataContextTests
    {
        public ControlGeneratorGenerationDataContextTests()
        {
            // nothing
        }

        ControlGeneratorGenerationDataContext dataContext;

        [TestInitialize]
        public void TestInitialize()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            this.dataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);
        }

        [TestMethod]
        public void TestAttachedDependencyProperties()
        {
            Assert.AreEqual(2, this.dataContext.AttachedDependencyProperties.Count);
            Assert.AreEqual("A-ADP2", this.dataContext.AttachedDependencyProperties.ElementAt(0).Name);
            Assert.AreEqual("Z-ADP1", this.dataContext.AttachedDependencyProperties.ElementAt(1).Name);
        }

        [TestMethod]
        public void TestAutomationPeerArguments()
        {
            Assert.AreEqual("this", this.dataContext.AutomationPeerArguments);
        }

        [TestMethod]
        public void TestAutomationPeerName()
        {
            Assert.AreEqual("AutomationPeer", this.dataContext.AutomationPeerName);
        }

        [TestMethod]
        public void TestCompany()
        {
            Assert.AreEqual("My Company", this.dataContext.Company);
        }

        [TestMethod]
        public void TestCopyright()
        {
            Assert.AreEqual("A Copyright", this.dataContext.Copyright);
        }

        [TestMethod]
        public void TestDependencyProperties()
        {
            Assert.AreEqual(2, this.dataContext.DependencyProperties.Count);
            Assert.AreEqual("A-DP2", this.dataContext.DependencyProperties.ElementAt(0).Name);
            Assert.AreEqual("Z-DP1", this.dataContext.DependencyProperties.ElementAt(1).Name);
        }

        [TestMethod]
        public void TestHasAutomationPeer()
        {
            Assert.AreEqual(true, this.dataContext.HasAutomationPeer);
        }

        [TestMethod]
        public void TestLocalizationCategory()
        {
            Assert.AreEqual(LocalizationCategory.CheckBox, this.dataContext.LocalizationCategory);
        }

        [TestMethod]
        public void TestLocalizationModifiability()
        {
            Assert.AreEqual(Modifiability.Modifiable, this.dataContext.LocalizationModifiability);
        }

        [TestMethod]
        public void TestLocalizationReadability()
        {
            Assert.AreEqual(Readability.Inherit, this.dataContext.LocalizationReadability);
        }

        [TestMethod]
        public void TestName()
        {
            Assert.AreEqual("ControlName", this.dataContext.Name);
        }

        [TestMethod]
        public void TestNamespace()
        {
            Assert.AreEqual("Control.Namespace", this.dataContext.Namespace);
        }

        [TestMethod]
        public void TestOptionalTemplatePartFactory()
        {
            Assert.AreEqual("OptionalTemplatePartFactory", this.dataContext.OptionalTemplatePartFactory);
        }

        [TestMethod]
        public void TestOutputFileName()
        {
            Assert.AreEqual("ControlName.Generated", this.dataContext.OutputFileName);
        }

        [TestMethod]
        public void TestOutputPath()
        {
            Assert.AreEqual("ALocation\\AnotherLocation", this.dataContext.OutputPath);
        }

        [TestMethod]
        public void TestOverrideStyleMetadata()
        {
            Assert.AreEqual(true, this.dataContext.OverrideStyleMetadata);
        }

        [TestMethod]
        public void TestPropertyChangedEventType()
        {
            Assert.AreEqual(PropertyChangedEventType.DotNetEvent, this.dataContext.PropertyChangedEventType);
        }

        [TestMethod]
        public void TestRemarks()
        {
            Assert.AreEqual("some remarks", this.dataContext.Remarks);
        }

        [TestMethod]
        public void TestRoutedCommandBindings()
        {
            Assert.AreEqual(4, this.dataContext.RoutedCommandBindings.Count);
            Assert.AreEqual("A-RC2", this.dataContext.RoutedCommandBindings.ElementAt(0).Name);
            Assert.AreEqual("A-RCB2", this.dataContext.RoutedCommandBindings.ElementAt(1).Name);
            Assert.AreEqual("Z-RC1", this.dataContext.RoutedCommandBindings.ElementAt(2).Name);
            Assert.AreEqual("Z-RCB1", this.dataContext.RoutedCommandBindings.ElementAt(3).Name);
        }

        [TestMethod]
        public void TestRoutedCommands()
        {
            Assert.AreEqual(2, this.dataContext.RoutedCommands.Count);
            Assert.AreEqual("A-RC2", this.dataContext.RoutedCommands.ElementAt(0).Name);
            Assert.AreEqual("Z-RC1", this.dataContext.RoutedCommands.ElementAt(1).Name);
        }

        [TestMethod]
        public void TestRoutedEvents()
        {
            Assert.AreEqual(2, this.dataContext.RoutedEvents.Count);
            Assert.AreEqual("A-RE2", this.dataContext.RoutedEvents.ElementAt(0).Name);
            Assert.AreEqual("Z-RE1", this.dataContext.RoutedEvents.ElementAt(1).Name);
        }

        [TestMethod]
        public void TestRoutedPropertyEventArgsFactory()
        {
            Assert.AreEqual("RoutedPropertyEventArgsFactory", this.dataContext.RoutedPropertyEventArgsFactory);
        }

        [TestMethod]
        public void TestSummary()
        {
            Assert.AreEqual("some summary", this.dataContext.Summary);
        }

        [TestMethod]
        public void TestTemplateFileName()
        {
            Assert.AreEqual("ControlGenerator.t4", this.dataContext.TemplateFileName);
        }

        [TestMethod]
        public void TestTemplatePartFactory()
        {
            Assert.AreEqual("TemplatePartFactory", this.dataContext.TemplatePartFactory);
        }

        [TestMethod]
        public void TestTemplateParts()
        {
            Assert.AreEqual(2, this.dataContext.TemplateParts.Count);
            Assert.AreEqual("A-TP2", this.dataContext.TemplateParts.ElementAt(0).Name);
            Assert.AreEqual("Z-TP1", this.dataContext.TemplateParts.ElementAt(1).Name);
        }

        [TestMethod]
        public void TestUsingNamespaces()
        {
            Assert.AreEqual(6, this.dataContext.UsingNamespaces.Count);
            Assert.AreEqual("ANamespace", this.dataContext.UsingNamespaces.ElementAt(0));
            Assert.AreEqual("System", this.dataContext.UsingNamespaces.ElementAt(1));
            Assert.AreEqual("System.ComponentModel", this.dataContext.UsingNamespaces.ElementAt(2));
            Assert.AreEqual("System.Windows", this.dataContext.UsingNamespaces.ElementAt(3));
            Assert.AreEqual("System.Windows.Input", this.dataContext.UsingNamespaces.ElementAt(4));
            Assert.AreEqual("ZNamespace", this.dataContext.UsingNamespaces.ElementAt(5));
        }

        [TestMethod]
        public void TestControlConfigurationNamespace()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            generatorConfig.Namespace = "Global.Namespace";
            controlConfig.Namespace = "Control.Namespace";

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);

            Assert.AreEqual("Control.Namespace", controlDataContext.Namespace);
        }

        [TestMethod]
        public void TestGeneratorConfigurationNamespace()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            generatorConfig.Namespace = "Global.Namespace";
            controlConfig.Namespace = null;

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);

            Assert.AreEqual("Global.Namespace", controlDataContext.Namespace);
        }

        [TestMethod]
        public void TestNoUsingNamespaces()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            controlConfig.UsingNamespaces = new List<string>();

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);

            Assert.AreEqual(4, controlDataContext.UsingNamespaces.Count);
            Assert.AreEqual("System", controlDataContext.UsingNamespaces.ElementAt(0));
            Assert.AreEqual("System.ComponentModel", controlDataContext.UsingNamespaces.ElementAt(1));
            Assert.AreEqual("System.Windows", controlDataContext.UsingNamespaces.ElementAt(2));
            Assert.AreEqual("System.Windows.Input", controlDataContext.UsingNamespaces.ElementAt(3));
        }

        [TestMethod]
        public void TestNoTemplateParts()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            controlConfig.TemplateParts = new List<ITemplatePartConfiguration>();

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);

            Assert.AreEqual(0, controlDataContext.TemplateParts.Count);
        }

        [TestMethod]
        public void TestNoRoutedCommandBindings()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            controlConfig.RoutedCommandBindings = new List<IRoutedCommandBindingConfiguration>();

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);

            Assert.AreEqual(2, controlDataContext.RoutedCommandBindings.Count);
            Assert.AreEqual("A-RC2", controlDataContext.RoutedCommandBindings.ElementAt(0).Name);
            Assert.AreEqual("Z-RC1", controlDataContext.RoutedCommandBindings.ElementAt(1).Name);
        }

        [TestMethod]
        public void TestNoRoutedCommands()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            controlConfig.RoutedCommands = new List<IRoutedCommandBindingConfiguration>();

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);

            Assert.AreEqual(0, controlDataContext.RoutedCommands.Count);
        }

        [TestMethod]
        public void TestNoRoutedEvents()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            controlConfig.RoutedEvents = new List<IRoutedEventConfiguration>();

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);

            Assert.AreEqual(0, controlDataContext.RoutedEvents.Count);
        }

        [TestMethod]
        public void TestNoDependencyProperties()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            controlConfig.DependencyProperties = new List<IDependencyPropertyConfiguration>();

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);

            Assert.AreEqual(0, controlDataContext.DependencyProperties.Count);
        }

        [TestMethod]
        public void TestNoAttachedDependencyProperties()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            controlConfig.AttachedDependencyProperties = new List<IAttachedDependencyPropertyConfiguration>();

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);

            Assert.AreEqual(0, controlDataContext.AttachedDependencyProperties.Count);
        }

        [TestMethod]
        public void TestDuplicateUsingNamespaces()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            var items = new List<string>();
            items.Add("Namespace.One");
            items.Add("Namespace.Two");
            items.Add("Namespace.One");

            controlConfig.UsingNamespaces = items;

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);

            Assert.AreEqual(6, controlDataContext.UsingNamespaces.Count);
            Assert.AreEqual("Namespace.One", controlDataContext.UsingNamespaces.ElementAt(0));
            Assert.AreEqual("Namespace.Two", controlDataContext.UsingNamespaces.ElementAt(1));
            Assert.AreEqual("System", controlDataContext.UsingNamespaces.ElementAt(2));
            Assert.AreEqual("System.ComponentModel", controlDataContext.UsingNamespaces.ElementAt(3));
            Assert.AreEqual("System.Windows", controlDataContext.UsingNamespaces.ElementAt(4));
            Assert.AreEqual("System.Windows.Input", controlDataContext.UsingNamespaces.ElementAt(5));
        }

        [TestMethod]
        public void TestDuplicateBuiltInUsingNamespaces()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            var items = new List<string>();
            items.Add("System");
            items.Add("System.ComponentModel");
            items.Add("System.Windows");

            controlConfig.UsingNamespaces = items;

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);

            Assert.AreEqual(4, controlDataContext.UsingNamespaces.Count);
            Assert.AreEqual("System", controlDataContext.UsingNamespaces.ElementAt(0));
            Assert.AreEqual("System.ComponentModel", controlDataContext.UsingNamespaces.ElementAt(1));
            Assert.AreEqual("System.Windows", controlDataContext.UsingNamespaces.ElementAt(2));
            Assert.AreEqual("System.Windows.Input", controlDataContext.UsingNamespaces.ElementAt(3));
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void TestDuplicateTemplateParts()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            var items = new List<ITemplatePartConfiguration>();
            items.Add(MockConfigurationHelp.CreateTemplatePartConfig("TPName", "MyType"));
            items.Add(MockConfigurationHelp.CreateTemplatePartConfig("TPName2", "MyType"));
            items.Add(MockConfigurationHelp.CreateTemplatePartConfig("TPName", "MyType2"));

            controlConfig.TemplateParts = items;

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void TestDuplicateDependencyProperties()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            var items = new List<IDependencyPropertyConfiguration>();
            items.Add(MockConfigurationHelp.CreateDependencyPropertyConfig("TPName", "MyType"));
            items.Add(MockConfigurationHelp.CreateDependencyPropertyConfig("TPName2", "MyType"));
            items.Add(MockConfigurationHelp.CreateDependencyPropertyConfig("TPName", "MyType2"));

            controlConfig.DependencyProperties = items;

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void TestDuplicateAttachedDependencyProperties()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            var items = new List<IAttachedDependencyPropertyConfiguration>();
            items.Add(MockConfigurationHelp.CreateAttachedDependencyPropertyConfig("TPName", "MyType"));
            items.Add(MockConfigurationHelp.CreateAttachedDependencyPropertyConfig("TPName2", "MyType"));
            items.Add(MockConfigurationHelp.CreateAttachedDependencyPropertyConfig("TPName", "MyType2"));

            controlConfig.AttachedDependencyProperties = items;

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void TestDuplicateRoutedCommands()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            var items = new List<IRoutedCommandBindingConfiguration>();
            items.Add(MockConfigurationHelp.CreateRoutedCommandConfig("TPName"));
            items.Add(MockConfigurationHelp.CreateRoutedCommandConfig("TPName2"));
            items.Add(MockConfigurationHelp.CreateRoutedCommandConfig("TPName"));

            controlConfig.RoutedCommands = items;

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void TestDuplicateRoutedCommandBindings()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            var items = new List<IRoutedCommandBindingConfiguration>();
            items.Add(MockConfigurationHelp.CreateRoutedCommandBindingConfig("TPName"));
            items.Add(MockConfigurationHelp.CreateRoutedCommandBindingConfig("TPName2"));
            items.Add(MockConfigurationHelp.CreateRoutedCommandBindingConfig("TPName"));

            controlConfig.RoutedCommandBindings = items;

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void TestDuplicateRoutedEvents()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            var items = new List<IRoutedEventConfiguration>();
            items.Add(MockConfigurationHelp.CreateRoutedEventConfig("TPName"));
            items.Add(MockConfigurationHelp.CreateRoutedEventConfig("TPName2"));
            items.Add(MockConfigurationHelp.CreateRoutedEventConfig("TPName"));

            controlConfig.RoutedEvents = items;

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);
        }

        [TestMethod]
        public void TestNoRoutedCommandsOrUsingNamespaces()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            controlConfig.UsingNamespaces = new List<string>();
            controlConfig.RoutedCommandBindings = new List<IRoutedCommandBindingConfiguration>();
            controlConfig.RoutedCommands = new List<IRoutedCommandBindingConfiguration>();

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);

            Assert.AreEqual(3, controlDataContext.UsingNamespaces.Count);
            Assert.AreEqual("System", controlDataContext.UsingNamespaces.ElementAt(0));
            Assert.AreEqual("System.ComponentModel", controlDataContext.UsingNamespaces.ElementAt(1));
            Assert.AreEqual("System.Windows", controlDataContext.UsingNamespaces.ElementAt(2));
        }

        [TestMethod]
        public void TestAddedNamespaceForRoutedCommands()
        {
            var generatorConfig = MockConfigurationHelp.CreateGeneratorConfig();
            var controlConfig = MockConfigurationHelp.CreateControlConfig("ControlName");

            controlConfig.UsingNamespaces = new List<string>();
            controlConfig.RoutedCommandBindings = new List<IRoutedCommandBindingConfiguration>();

            var items = new List<IRoutedCommandBindingConfiguration>();
            items.Add(MockConfigurationHelp.CreateRoutedCommandConfig("ACommand"));
            controlConfig.RoutedCommands = new List<IRoutedCommandBindingConfiguration>();

            var controlDataContext = new ControlGeneratorGenerationDataContext(generatorConfig, controlConfig);

            Assert.AreEqual(3, controlDataContext.UsingNamespaces.Count);
            Assert.AreEqual("System", controlDataContext.UsingNamespaces.ElementAt(0));
            Assert.AreEqual("System.ComponentModel", controlDataContext.UsingNamespaces.ElementAt(1));
            Assert.AreEqual("System.Windows", controlDataContext.UsingNamespaces.ElementAt(2));
        }

    }
}
